package com.gopay.common.cps.service.autosettle.util;

import com.gopay.common.constants.autosettle.PayRouteResp;
import com.gopay.common.constants.autosettle.SettlementExchangeConstants;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.trans.BCFlag;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.FastJsonUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @description 付款路由工具类
 * @author jianghp
 * @date 2018/4/17 10:08
 * Copyright (c) 2018. www.gopay.com.cn Inc.All rights reserved.
 */
@Service(value = "payRouteUtils")
public class PayRouteUtils {
	
	private static final Logger logger = LoggerFactory.getLogger(PayRouteUtils.class);

    @Resource(name = "payRouteHelper")
    private PayRouteHelper payRouteHelper;

	public PayRouteResp choosePayBankCode(CpsGenMainOrder mainOrder, String bankName, String bcFlag, String cardNum, String custId, String acctId,String splitFlag){
		PayRouteResp resp = new PayRouteResp();
		String gopayOrderId = mainOrder.getGopayOrderId();
		resp.setGopayOrderId(gopayOrderId);
		StopWatch sw = new StopWatch();
		sw.start();
		logger.info("★★★★★★付款单订单号：{}，获取付款路由step0★★★★★★★★★★开始时间：{}",gopayOrderId, DateUtils.getCurrDate());
		try {
			//step1 先查询付款客户对应的自动结算银行是否存在
			String autoSettleBanks = payRouteHelper.queryPayBankCodeByAutoSettle(mainOrder,acctId);
			logger.info("step1付款单订单号：{}，付款账户：{}，交易码：{}，获取的自动结算当前支持的银行为：{}",new String[]{gopayOrderId,acctId,mainOrder.getGopayIntTxnCd(),autoSettleBanks});
			if(StringUtils.isBlank(autoSettleBanks)){
				return initPayRouteResp(resp,null,null,sw);
			}
			//step2 根据收款银行名称匹配银行收款银行code
			String receiveBankCode = payRouteHelper.switchBankCodeByName(gopayOrderId, bankName);
			logger.info("step2付款单订单号：{}，根据收款银行名称：{} --》转换成银行代码为：{}",new String[]{gopayOrderId,bankName,receiveBankCode});
			if(StringUtils.isBlank(receiveBankCode)){
				return initPayRouteResp(resp,null,null,sw);
			}
			//step3 获取付款路由方案规则所匹配的付款汇路
			List<String> stlmExs= choosePayRoute(mainOrder,bcFlag, custId,splitFlag,receiveBankCode);
			logger.info("step3付款单订单号：{}，获取付款路由方案规则所匹配的付款汇路为：{}",gopayOrderId, FastJsonUtil.toJSONString(stlmExs));
			if(stlmExs == null || stlmExs.isEmpty()){
				return initPayRouteResp(resp,null,null,sw);
			}
			//step4 路由方案规则 和自动结算 银行匹配
			List<String> autoSettleList = Arrays.asList(autoSettleBanks.split(","));
			for(String stlmEx : stlmExs ){
				String bankCode = convertBankCode(stlmEx);
				if(autoSettleList.contains(bankCode)){
					if(SettlementExchangeConstants.STLM_EX_ICBC_CROSS.equalsIgnoreCase(stlmEx)){
						//如果匹配的接口通道是 工行大额
						if(payRouteHelper.useCross(mainOrder, bankName, bcFlag, cardNum)){
							return initPayRouteResp(resp,BankConstants.BANK_LOGO_ICBC,stlmEx,sw);
						}
						continue;
					}
					if(SettlementExchangeConstants.STLM_EX_ICBC_SUPER.equalsIgnoreCase(stlmEx)){
						//如果匹配的接口通道是 工行超级网银
						if(payRouteHelper.useSuper(mainOrder, bankName, bcFlag, cardNum)){
							return initPayRouteResp(resp,BankConstants.BANK_LOGO_ICBC,stlmEx,sw);
						}
						continue;
					}
					if(SettlementExchangeConstants.STLM_EX_NUCCPAY.equalsIgnoreCase(stlmEx)){
						//通道如果是网联支付
						String code = chooseNuccPayChannel(receiveBankCode);
						return initPayRouteResp(resp,code,stlmEx,sw);
					}
					return initPayRouteResp(resp,bankCode,stlmEx,sw);
				}
			}
			logger.info("付款单订单号：{}，付款路由和支持的自动结算银行未匹配上",gopayOrderId);
		}catch (Exception e){
			logger.error("★★★★★★付款单订单号：{}，获取付款路由异常=====",gopayOrderId, e);
		}
		return initPayRouteResp(resp,null,null,sw);
	}

	/**
	 * 获取网联支付的出款通道
	 * @param receiveBankCode
	 * @return
	 */
	private String chooseNuccPayChannel(String receiveBankCode) {
		return payRouteHelper.chooseNuccPayChannel(receiveBankCode);
	}

	//初始化响应类
	private PayRouteResp initPayRouteResp(PayRouteResp resp,String bankCode,String stlmEx,StopWatch sw){
		resp.setBankCode(bankCode);
		resp.setStlmEx(stlmEx);
		sw.stop();
		long spendTime = sw.getTime();
		long sec = spendTime / 1000;
		long ns = spendTime % 1000;
		logger.info("★★★★★★付款单订单号：{}，获取付款路由step4★★★★★★★★★★银行代码：{}，结算汇路：{}，总耗时：{}秒{}毫秒",new String[]{resp.getGopayOrderId(),bankCode,stlmEx,String.valueOf(sec), String.valueOf(ns)});
		return resp;
	}
	/**
	 * 根据汇路返回银行代码 (汇路和银行代码不一致的维护在这里)
	 * @param stlmEx
	 * @return
	 */
	private String convertBankCode(String stlmEx) {
		if(SettlementExchangeConstants.STLM_EX_CMB_P.equalsIgnoreCase(stlmEx)
				|| SettlementExchangeConstants.STLM_EX_CMB_C.equalsIgnoreCase(stlmEx)){
			return BankConstants.BANK_LOGO_CMB;
		}
		return stlmEx;
	}

	/**
	 * 获取路由规则
	 * @param mainOrder
	 * @param bcFlag
	 * @param custId
	 * @param splitFlag
	 * @param receiveBankCode
	 * @return
	 */
	private List<String> choosePayRoute(CpsGenMainOrder mainOrder,String bcFlag, String custId,String splitFlag,String receiveBankCode) {
		//step1  先查询商是否个性化过
		Boolean isSpec = payRouteHelper.isSpecialRoute(custId);
		List<String> routes = null;
		if(isSpec){
			//step2.1 个性化路由查询
			routes = payRouteHelper.chooseSpecialRoute(mainOrder,bcFlag,splitFlag,receiveBankCode,custId);
		}
		if(routes == null || routes.isEmpty()){
			//step2.2 通用路由查询
			routes = payRouteHelper.chooseCommonRoute(mainOrder,bcFlag,splitFlag,receiveBankCode);
		}
		//step3 接口通道和银行代码的转换
		List<String> stlmExs = new ArrayList<>();
		if(routes != null && !routes.isEmpty()){
			for(String route : routes){
				if(BisBankInterfaceChannel._00.value.equals(route)){
					//直连银行通道直接返回同行代码
					if(BankConstants.BANK_LOGO_CMB.equalsIgnoreCase(receiveBankCode)){
						if(StringUtils.equals(bcFlag, BCFlag.BC_FLAG_P.value)){
							//招商对私
							stlmExs.add(SettlementExchangeConstants.STLM_EX_CMB_P);
						}else{
							//招商对公
							stlmExs.add(SettlementExchangeConstants.STLM_EX_CMB_C);
						}
					}else{
						stlmExs.add(receiveBankCode);
					}
				}else if(BisBankInterfaceChannel._18.value.equals(route)){
					//网联直接返回网联支付
					stlmExs.add(SettlementExchangeConstants.STLM_EX_NUCCPAY);
				}else if(BisBankInterfaceChannel._22.value.equals(route)){
					//工行大额返回工行大额
					stlmExs.add(SettlementExchangeConstants.STLM_EX_ICBC_CROSS);
				}else if(BisBankInterfaceChannel._21.value.equals(route)){
					//工行超级网银返回工行超级网银
					stlmExs.add(SettlementExchangeConstants.STLM_EX_ICBC_SUPER);
				}
			}
		}
		return stlmExs;
	}

}
